<template>
    <div class="demo-split">
        <Split v-model="split">
            <template #left>
                <div class="demo-split-pane">
                    <el-space>
                        <el-button
                            type="primary"
                            plain
                            icon="Plus"
                            @click="startInsert('')"
                        ></el-button>
                        <el-input placeholder="请输入查询字符" clearable v-model="searchPrefix">
                        </el-input>
                        <el-button type="primary" icon="Search" @click="search()"></el-button>
                    </el-space>
                    <el-table :data="tableData" @row-click="handleRowClick" style="margin-top: 10px">
                        <el-table-column fixed prop="name" label="Name"/>
                        <el-table-column align="right" label="Operations">
                            <template #default="scope">
                                <el-button link type="primary" size="small" icon="View"
                                           @click="startDetail(scope.row)"></el-button>
                                <el-button link type="primary" size="small" icon="Stamp" @click="startGrant(scope.row)"></el-button>
                                <el-button link type="primary" size="small" icon="Remove" @click="startRevoke(scope.row)"></el-button>
                                <el-button link type="primary" size="small" icon="Delete"
                                           @click="startDelete(scope.row)"></el-button>
                            </template>
                        </el-table-column>
                    </el-table>
                    <el-dialog
                        title="Add Role"
                        v-model="insertFormShow"
                        width="500"
                    >
                        <el-form ref="insertFormRef" :model="insertForm" :rules="insertFormRules" :label-width="120"
                                 label-position="left">
                            <el-form-item label="name" prop="name">
                                <el-input v-model="insertForm.name" placeholder="请保证 name 唯一"/>
                            </el-form-item>
                        </el-form>
                        <template #footer>
                            <div style="display: flex; justify-content: space-between; align-items: center;">
                                <div>
                                    <el-button @click="insertFormShow = false">取消</el-button>
                                    <el-button type="primary" @click="confirmInsert">确定</el-button>
                                </div>
                            </div>
                        </template>
                    </el-dialog>
                    <el-dialog
                        title="用户授权"
                        v-model="grantFormShow"
                        width="500"
                    >
                        <el-form ref="grantFormRef" :model="grantForm" :rules="grantFormRules" :label-width="120" label-position="left">
                            <el-form-item label="role" prop="role">
                                <el-input :disabled="grantForm.roleReadOnly" v-model="grantForm.role"
                                          placeholder="请保证名称唯一, 否则会覆盖同名的链接信息"/>
                            </el-form-item>
                            <el-form-item label="read" prop="read">
                                <el-input v-model="grantForm.read" placeholder="示例 http://192.168.0.1:8080"/>
                            </el-form-item>
                            <el-form-item label="write" prop="write">
                                <el-input v-model="grantForm.write" placeholder="示例 http://192.168.0.1:8080"/>
                            </el-form-item>
                        </el-form>
                        <template #footer>
                            <el-space>
                                <el-button @click="grantFormShow = false">取消</el-button>
                                <el-button type="primary" @click="confirmGrant">确定</el-button>
                            </el-space>
                        </template>
                    </el-dialog>
                </div>
            </template>
            <template #right>
                <div v-if="!!permNode.name" class="demo-split-pane">
                    <el-space style="padding: 3px;">
                        <el-tag size="large" type="warning" effect="plain"> Role = {{ permNode.name }}</el-tag>
                        <el-input  placeholder="请输入查询字符" clearable v-model="permPrefix"/>
                        <el-button type="primary" icon="Search" @click="permSearch()"></el-button>
                    </el-space>
                    <div class="demo-split">
                        <Split ref="permSplitRef" v-model="permSplit">
                            <template #left>
                                <el-table :data="permRead" >
                                    <el-table-column prop="name" label="Read Permission"/>
                                    <el-table-column align="right" label="Operations">
                                        <template #default="scope">
                                            <el-button link type="primary" size="small" icon="Remove" @click="startRevoke('read',scope.row)"></el-button>
                                        </template>
                                    </el-table-column>
                                </el-table>
                            </template>
                            <template #right>
                                <el-table :data="permWrite">
                                    <el-table-column fixed prop="name" label="Write Permission"/>
                                    <el-table-column align="right" label="Operations">
                                        <template #default="scope">
                                            <el-button link type="primary" size="small" icon="Remove" @click="startRevoke('write',scope.row)"></el-button>
                                        </template>
                                    </el-table-column>
                                </el-table>
                            </template>
                        </Split>
                    </div>
                </div>
            </template>
        </Split>
    </div>
</template>

<script setup>
import {ref, defineProps, onMounted} from "vue";
import {ElMessage, ElMessageBox} from 'element-plus';
import {Search} from "@element-plus/icons-vue";
import {
    cluster_version,
    etcd_keys_list,
    etcd_keys_post,
    etcd_keys_delete,
    etcd_keys_put,
    auth_user_get,
    auth_role_list, auth_role_get, auth_role_add,auth_role_delete,
    auth_role_grant,auth_role_revoke,
} from "@/api/etcd2.js"
import {List, ListItem, Split} from "view-ui-plus";

const props = defineProps({
    connect: {
        type: Object,
        default: {
            name: '默认标题',
            url: 'http://127.0.0.1:2379',
            version: 'v2',
            username: 'root',
            password: '123456'
        }
    }
})

const split = ref(0.4)
const permSplit = ref(0.5)
const tableData = ref([
    {
        name: 'Tom',
        read: ['California'],
        write: ['California'],
    }
])

const handleClick = () => {
    console.log('click')
}

// 新增
const insertFormShow = ref(false);
const insertFormRef = ref(null)
const insertForm = ref({
    name: '',
    password: ''
})
const insertFormRules = ref({
    name: [
        {required: true, message: 'Please input ID', trigger: 'blur'},
        {min: 1, message: 'Length should be greater than 1', trigger: 'blur'},
    ]
})

function startInsert() {
    insertFormShow.value = true;
    insertForm.value.name = null;
    insertForm.value.password = null;
}

function confirmInsert() {
    insertFormRef.value.validate((valid) => {
        if (valid) {
            // 关闭弹框
            insertFormShow.value = false;
            // 执行新增逻辑
            let url = props.connect.url;
            let user = insertForm.value.name;
            auth_role_add(url, user)
                .then(res => {
                    ElMessage.success('auth_role_add ' + 'success');
                    // 重新查询
                    search();
                })
                .catch(error => {
                    console.log(error);
                    let message = error.response.data.message;
                    ElMessage.error('auth_role_add ' + message);
                });

        }
    });
}

// 详情信息
const permNode = ref({})
const permRead = ref([
    {
        "permType": "READWRITE",
        "key": "YWFh"
    }
])
const permWrite = ref([
    {
        "permType": "READWRITE",
        "key": "YWFh"
    }
])
const permPrefix = ref(null)

const handleRowClick = (row, column, event) => {
    startDetail(row);
};

function startDetail(row) {
    permNode.value = row;
    permPrefix.value = null;
    permSearch();
}

function startRevoke(type,row) {
    ElMessageBox.confirm(
        'Permanently delete the node. Continue?',
        'Warning',
        {
            confirmButtonText: 'OK',
            cancelButtonText: 'Cancel',
            type: 'warning',
        }
    )
        .then(() => {
            confirmRevoke(type,row);
        })
        .catch(() => {
            // do nothing
        })
}

function confirmRevoke(type,row) {
    let role = permNode.value.name;
    let key = row.name;
    // 执行新增逻辑
    let data = {};
    if(type==='read'){
        data = {
            "role" : role,
            "revoke" : {
                "kv" : {
                    "read": [
                        key
                    ]
                }
            }
        };
    }else{
        data = {
            "role" : role,
            "revoke" : {
                "kv" : {
                    "write": [
                        key
                    ]
                }
            }
        };
    }
    let url = props.connect.url;
    auth_role_revoke(url, role,data)
        .then(res => {
            ElMessage.success('auth_role_revoke ' + 'success');
            // 重新查询
            permSearch();
        })
        .catch(error => {
            let message = error.response.data.message || error.message;
            ElMessage.error('auth_role_revoke ' + message);
        });

}

function permSearch() {
    let url = props.connect.url;
    let row = permNode.value;
    permRead.value = [];
    permWrite.value = [];
    auth_role_get(url, row.name)
        .then(res => {
            let result = res.data;
            if (!!result.permissions) {
                let read = result.permissions.kv.read;
                if(!!read){
                    let rows = [];
                    for (let i = 0; i < read.length; i++) {
                        let item = read[i];
                        if(!!permPrefix.value){
                            if(item.includes(permPrefix.value)){
                                rows.push({name:item});
                            }
                        }else{
                            rows.push({name:item});
                        }
                    }
                    permRead.value=rows;
                }

                let write= result.permissions.kv.write;
                if(!!write){
                    let rows = [];
                    for (let i = 0; i < write.length; i++) {
                        let item = write[i];
                        if(!!permPrefix.value){
                            if(item.includes(permPrefix.value)){
                                rows.push({name:item});
                            }
                        }else{
                            rows.push({name:item});
                        }
                    }
                    permWrite.value=rows;
                }
            }
        })
        .catch(error => {
            let message = error.message || error.response.data.message;
            ElMessage.error('auth_role_get ' + message);
        })
}

// 用户授权
const grantFormShow = ref(false);
const grantFormRef = ref(null)
const grantForm = ref({
    role: '',
    roleReadOnly: false,
    read: '',
    write: '',
})

const grantFormRules = ref({
    role: [
        {required: true, message: 'Please input role', trigger: 'blur'},
        {min: 1, message: 'Length should be greater than 3', trigger: 'blur'},
    ],
    permission: [
        {required: true, message: 'Please input role', trigger: 'blur'},
        {min: 1, message: 'Length should be greater than 3', trigger: 'blur'},
    ],
})

function startGrant(row) {
    grantFormShow.value = true;
    grantForm.value.role = row.name;
    grantForm.value.roleReadOnly = true;
    grantForm.value.permission = '';
}

function confirmGrant() {
    grantFormRef.value.validate((valid) => {
        if (valid) {
            // 关闭弹框
            grantFormShow.value = false;
            let role = grantForm.value.role;
            let read = grantForm.value.read;
            let write = grantForm.value.write;
            // 执行新增逻辑
            let grant = {
                "role" : role,
                "grant" : {
                    "kv" : {
                        "read": [
                            read
                        ],
                        "write": [
                            write
                        ]
                    }
                }
            };
            let url = props.connect.url;
            auth_role_grant(url, role,grant)
                .then(res => {
                    ElMessage.success('auth_role_grant ' + 'success');
                    // 重新查询
                    permSearch();
                })
                .catch(error => {
                    let message = error.response.data.message || error.message;
                    ElMessage.error('auth_role_grant ' + message);
                });

        }
    });
}


// 删除
function startDelete(row) {
    ElMessageBox.confirm(
        'Permanently delete the node. Continue?',
        'Warning',
        {
            confirmButtonText: 'OK',
            cancelButtonText: 'Cancel',
            type: 'warning',
        }
    )
        .then(() => {
            confirmDelete(row);
        })
        .catch(() => {
            // do nothing
        })
}

function confirmDelete(row) {
    let url = props.connect.url;
    let name = row.name;
    auth_role_delete(url, name)
        .then(response => {
            search();
        })
        .catch(error => {
            let message = error.response.data.message;
            ElMessage.error('auth_role_delete ' + message);
        });
}

// 查询
const searchPrefix = ref(null);
const search = () => {
    let con = {};
    let temp = props.connect;
    console.log(props)
    console.log(props.connect)
    con.url = props.connect.url;
    con.version = props.connect.version;
    let auth = {};
    auth.username = props.connect.username;
    auth.password = props.connect.password;
    auth_role_list(con.url, con.version, auth)
        .then(res => {
            console.log(res);
            tableData.value = [];
            let roles = [];
            let items = res.data.roles;
            if (Array.isArray(items)) {
                for (let i = 0; i < items.length; i++) {
                    // nodes[i].hasChildren =false;
                    // nodes[i].children = []
                    let u = {};
                    u.name = items[i].role;
                    u.read = items[i].permissions.kv.read;
                    u.write = items[i].permissions.kv.read;
                    if(!!searchPrefix.value){
                        if(u.name.includes(searchPrefix.value)){
                            roles.push(u);
                        }else{
                            continue;
                        }
                    }else{
                        roles.push(u);
                    }
                }
                roles.sort((a, b) => {
                    return a.name.localeCompare(b.name);
                });
                tableData.value = roles;
            }
        })
        .catch(error => {
            ElMessage.error('UsersEtcd:' + error.message)
        })
}

onMounted(() => {
    search();
})

</script>